package com.aplink.generic;

import android.app.ActionBar;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTabHost;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;

import com.aplink.generic.adapter.GenericConfigAdapter;
import com.aplink.generic.constant.ConfigParameter;
import com.aplink.generic.constant.ControlType;
import com.aplink.generic.controller.AppGenericController;
import com.aplink.generic.database.DatabaseHelper;
import com.aplink.generic.database.ISaveCommand;
import com.aplink.generic.database.ISelectCommand;
import com.aplink.generic.database.IUpdateCommand;
import com.aplink.generic.handler.GenericHandler;
import com.aplink.generic.pojo.GenericAttribute;
import com.aplink.generic.pojo.GenericObject;
import com.aplink.generic.pojo.ObjPropCol;
import com.aplink.generic.pojo.ObjPropInfo;
import com.aplink.generic.pojo.ObjPropValue;
import com.aplink.generic.pojo.controlspec.ControlSpec;
import com.aplink.generic.pojo.controlspec.MenuSpec;
import com.aplink.generic.util.AndroidUIParser;
import com.aplink.generic.widgets.BaseView;
import com.aplink.generic.widgets.CustomButton;
import com.aplink.generic.widgets.CustomEdittext;
import com.aplink.generic.widgets.CustomGridView;
import com.aplink.generic.widgets.CustomImageView;
import com.aplink.generic.widgets.CustomListView;
import com.aplink.generic.widgets.CustomSpinner;
import com.aplink.generic.widgets.CustomTabhost;
import com.aplink.generic.widgets.CustomTextview;
import com.aplink.generic.widgets.CustomViewPager;
import com.aplink.generic.xmlparser.ControlSpecParser;
import com.aplink.generic.xmlparser.ObjPropInfoParser;

import java.util.ArrayList;
import java.util.HashMap;

public abstract class GenericFragment extends Fragment {

    public static final int NONE = 0;
    public static final int RELOAD_DATA = 2;
    private GenericConfigAdapter mAdapterListView;
    private int mContentDataFileId;
    private ArrayList<ControlSpec> mControlSpecList;
    private CustomGridView mCustomGridView = null;
    private DatabaseHelper mDbManager;
    private int mFormDesignFileId;
    private GenericHandler mHandler;
    private HashMap<String, String> mHashPassedValues;
    private ArrayList<ObjPropInfo> mObjPropList;
    private ActionBar mActionBar;
    private HashMap<String, ControlSpec> mOptionMenu;
    private CustomListView mCustomListView;

    public abstract int getFormDesign();

    public abstract int getContentData();

    public abstract String getTable();

    private final AdapterView.OnItemSelectedListener mOnItemSelectedListener = new AdapterView.OnItemSelectedListener() {

        @Override
        public void onItemSelected( AdapterView<?> adapter, View v,
                                    int position, long arg3 ) {
            handleSelectedItemEvent( adapter, v, position );
        }

        @Override
        public void onNothingSelected( AdapterView<?> arg0 ) {

        }
    };
    private GenericObject mPassedGenericObject;

    private String mTable;

    private HashMap<String, BaseView> mViewsInLayout;

    private HashMap<View, ControlSpec> mControlSpecOfView;

    private final View.OnClickListener onViewClickListener = new View.OnClickListener() {

        @Override
        public void onClick( View v ) {
            onHandleControlClickEvent( (ControlSpec) v.getTag() );
        }
    };

    private void registerForContextMenu() {

    }

    protected void handleContextMenuClickEvent() {

    }

    public String getClassName() {
        return ( (Object) this ).getClass().getSimpleName();
    }

    protected void handleSelectedItemEvent( AdapterView<?> adapter, View v,
                                            int position ) {

    }

    protected abstract void onHandleControlClickEvent( ControlSpec controlSpec );

    protected void initData() {
        if ( this.mPassedGenericObject != null ) {
            ArrayList<GenericAttribute<?, ?>> genericAttList = this.mPassedGenericObject
                    .getAttributeList();
            this.mHashPassedValues = new HashMap<String, String>();

            for ( int i = 0 ; i < genericAttList.size() ; i++ ) {
                final String name = genericAttList.get( i ).getName().toString();
                String value;
                if ( genericAttList.get( i ).getValue() == null ) {
                    value = "";
                } else {
                    value = genericAttList.get( i ).getValue().toString();
                }
                this.mHashPassedValues.put( name, value );
            }
        }
    }

    private String getCurrentFragment() {
        int length = getFragmentManager().getFragments().size();
        return getFragmentManager().getFragments().get( length - 1 ).toString();
    }

    protected void loadDataToForm() {
        for ( final ControlSpec controlSpec : this.getControlSpecList() ) {
            final ControlType controlType = controlSpec.getControlType();
            if ( controlType.equals( ControlType.ActionBarMenu ) ) {
                mOptionMenu.put( getCurrentFragment(), controlSpec );
                getActivity().invalidateOptionsMenu();
            } else if ( controlType.equals( ControlType.ContextMenu ) ) {
                this.registerForContextMenu();
            } else {
                int controlId = AndroidUIParser.getViewIdByName( controlSpec
                        .getControlId() );
                if ( controlType.equals( ControlType.FragmentTabHost ) ) {
                    controlId = android.R.id.tabhost;
                }
                if ( controlId == AndroidUIParser.RESOURCE_NOT_FOUND ) {
                    continue;
                }
                View view = mView.findViewById( controlId );
                BaseView baseView = null;
                if ( ( view instanceof Button )
                        && view.getClass().equals( Button.class ) ) {
                    baseView = new CustomButton( this, controlSpec, view );
                } else if ( ( view instanceof TextView )
                        && view.getClass().equals( TextView.class ) ) {
                    baseView = new CustomTextview( this, controlSpec, view );
                } else if ( ( view instanceof ListView )
                        && view.getClass().equals( ListView.class ) ) {
                    baseView = new CustomListView( this, controlSpec, view );
                    mCustomListView = (CustomListView) baseView;
                } else if ( ( view instanceof GridView )
                        && view.getClass().equals( GridView.class ) ) {
                    baseView = new CustomGridView( this, controlSpec, view );
                    mCustomGridView = (CustomGridView) baseView;
                } else if ( ( view instanceof EditText )
                        && view.getClass().equals( EditText.class ) ) {
                    baseView = new CustomEdittext( this, controlSpec, view );
                } else if ( ( view instanceof Spinner )
                        && view.getClass().equals( Spinner.class ) ) {
                    baseView = new CustomSpinner( this, controlSpec, view );
                } else if ( ( view instanceof ViewPager )
                        && view.getClass().equals( ViewPager.class ) ) {
                    baseView = new CustomViewPager( this, controlSpec, view );
                } else if ( ( view instanceof FragmentTabHost )
                        && view.getClass().equals( FragmentTabHost.class ) ) {
                    baseView = new CustomTabhost( this, controlSpec, view );
                } else if ( ( view instanceof ImageView )
                        && view.getClass().equals( ImageView.class ) ) {
                    baseView = new CustomImageView( this, controlSpec, view );
                }
                if ( baseView != null ) {
                    baseView.initView();
                    mViewsInLayout.put( controlSpec.getControlId(), baseView );
                    mControlSpecOfView.put( view, controlSpec );
                }
            }
        }
    }

    protected void onHandleOptionMenuClickEvent( MenuSpec.MenuItem menuItem ) {

    }

    public GenericConfigAdapter getAdapterListView() {
        return this.mAdapterListView;
    }

    public ArrayList<ControlSpec> getControlSpecList() {
        if ( this.mControlSpecList == null ) {
            this.mControlSpecList = ControlSpecParser.parserIntoControls(
                    getActivity().getApplicationContext(),
                    this.mFormDesignFileId, ConfigParameter.CONTROL_SPECS );
        }
        return this.mControlSpecList;
    }

    public CustomGridView getCustomGallery() {
        return mCustomGridView;
    }

    public DatabaseHelper getDBHelper() {
        return this.mDbManager;
    }

    public GenericHandler getHandler() {
        if ( mHandler == null ) {
            mHandler = new GenericHandler();
        }
        return this.mHandler;
    }

    public HashMap<String, String> getHashPassedValues() {
        return this.mHashPassedValues;
    }

    private ObjPropCol mObjPropCol;

    public ObjPropCol getObjPropCol() {
        if ( mObjPropCol == null ) {
            mObjPropCol = ObjPropInfoParser.parseIntoObjProp( getActivity()
                    .getApplicationContext(), this.mContentDataFileId,
                    ConfigParameter.OBJ_PROP_TAGNAME, this.mTable );
        }
        return mObjPropCol;
    }

    public ArrayList<ObjPropInfo> getObjPropList() {
        if ( this.mObjPropList == null ) {
            this.mObjPropList = getObjPropCol().GetBaseList();
        }
        return this.mObjPropList;
    }

    public ArrayList<ObjPropValue> getObjPropValues() {
        final ArrayList<ObjPropValue> objPropValueList = new ArrayList<ObjPropValue>();
        for ( final ControlSpec controlSpec : this.mControlSpecList ) {
            BaseView baseView = mViewsInLayout.get( controlSpec.getControlId() );
            GenericAttribute<?, ?> attribute = baseView.getAttribute();
            if ( attribute != null ) {
                ObjPropValue objPropvalue = new ObjPropValue(
                        controlSpec.getMappingName(), attribute );
                objPropValueList.add( objPropvalue );
            }
        }
        return objPropValueList;
    }

    public AdapterView.OnItemSelectedListener getOnItemSelectedListener() {
        return mOnItemSelectedListener;
    }

    public View.OnClickListener getOnViewClickListener() {
        return this.onViewClickListener;
    }

    public GenericObject getPassedGenericObject() {
        return this.mPassedGenericObject;
    }

    public HashMap<String, BaseView> getViewsInLayout() {
        return this.mViewsInLayout;
    }

    public ISaveCommand insertCommand() {
        return (ISaveCommand) mDbManager;
    }

    @Override
    public void onCreate( Bundle arg0 ) {
        super.onCreate( arg0 );
        this.mDbManager = new DatabaseHelper( AppGenericController.getInstance().getDatabaseManager() );
        mContentDataFileId = getContentData();
        mFormDesignFileId = getFormDesign();
        mTable = getTable();
        setHasOptionsMenu( true );
        this.mObjPropList = this.getObjPropList();
        this.mControlSpecList = this.getControlSpecList();
        this.mHandler = new GenericHandler();
        this.mViewsInLayout = new HashMap<String, BaseView>();
        this.mAdapterListView = new GenericConfigAdapter();
        mOptionMenu = new HashMap<String, ControlSpec>();
        mControlSpecOfView = new HashMap<View, ControlSpec>();
    }

    private View mView;

    @Override
    public View onCreateView( LayoutInflater inflater, ViewGroup container,
                              Bundle savedInstanceState ) {
        if ( getContentView() != NONE ) {
            mView = inflater.inflate( getContentView(), container, false );
        }
        return mView;
    }

    public abstract int getContentView();

    @Override
    public void onCreateOptionsMenu( Menu menu, MenuInflater inflater ) {
        if ( mOptionMenu != null ) {
            ControlSpec menuControlSpec = mOptionMenu.get( getCurrentFragment() );
            if ( menuControlSpec != null ) {
                int optionMenuRes = AndroidUIParser
                        .getMenuIdByName( menuControlSpec.getControlId() );
                inflater.inflate( optionMenuRes, menu );
                super.onCreateOptionsMenu( menu, inflater );
            } else {
                menu.clear();
            }
        }
    }

    @Override
    public boolean onOptionsItemSelected( MenuItem item ) {
        ControlSpec menuControlSpec = mOptionMenu.get( getCurrentFragment() );
        if ( menuControlSpec != null ) {
            MenuSpec customMenu = (MenuSpec) menuControlSpec;
            for ( MenuSpec.MenuItem menuItem : customMenu.getMenuItems() ) {
                if ( menuItem.getIdValue() == item.getItemId() ) {
                    this.onHandleOptionMenuClickEvent( menuItem );
                    return true;
                }
            }
        }

        return super.onOptionsItemSelected( item );
    }

    public ISelectCommand selectCommand() {
        return (ISelectCommand) mDbManager;
    }

    public void setAdapterListView( GenericConfigAdapter adapterListView ) {
        this.mAdapterListView = adapterListView;
    }

    public void setControlSpecList( ArrayList<ControlSpec> controlSpecList ) {
        this.mControlSpecList = controlSpecList;
    }

    public void setDBHelper( DatabaseHelper dBHelper ) {
        this.mDbManager = dBHelper;
    }

    public void setObjPropList( ArrayList<ObjPropInfo> objPropList ) {
        this.mObjPropList = objPropList;
    }

    public void setPassedGenericObject( GenericObject passedGenericObject ) {
        this.mPassedGenericObject = passedGenericObject;
    }

    public IUpdateCommand updateCommand() {
        return (IUpdateCommand) mDbManager;
    }

    public Context getApplicationContext() {
        return getActivity();
    }

    public void finishActivity() {
        getActivity().finish();
    }

    public ActionBar getActivityActionBar() {
        return getActivity().getActionBar();
    }

    public CustomListView getCustomListView() {
        return mCustomListView;
    }

    public void setCustomListView( CustomListView customListView ) {
        mCustomListView = customListView;
    }

}
